#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

namespace Protocal // 协议
{
    const std::string SEP = "\r\n";

    // len\r\n{}\r\n
    std::string Decode(std::string& buffer)
    {
        int pos = buffer.find(SEP);
        if(pos == std::string::npos) return "";

        std::string str = buffer.substr(0, pos);
        if(str.empty()) return "";

        int total = stoi(str) + str.size() + 2 * SEP.size();
        if(buffer.size() < total) return "";

        std::string ret = buffer.substr(pos+SEP.size(), stoi(str));
        buffer.erase(0, total);

        return ret; 
    }

    // len\r\n{}\r\n
    void Encode(std::string& buffer) //buffer是Json串
    {
        int str_len = buffer.size();

        std::string ret = std::to_string(str_len) + SEP + buffer + SEP;
        buffer = ret;
    }

    class Request
    {
    public:
        int _x;
        int _y;
        char _oper;

    public:
        Request(){}

        Request(int x, int y, char oper)
            : _x(x), _y(y), _oper(oper)
        {
        }

        std::string Serislize()
        {
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["oper"] = _oper;

            Json::FastWriter writer;
            std::string str = writer.write(root);

            return str;
        }

        bool DeSerislize(std::string &str)
        {
            Json::Value root;
            Json::Reader reader;

            int ret = reader.parse(str, root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();

            return ret;
        }
    };

    class Response
    {
    public:
        int _ret;
        int _code;

    public:
        Response(){}

        Response(int ret, int code = 0)
            : _ret(ret), _code(code)
        {
        }

        std::string Serislize()
        {
            Json::Value root;
            root["ret"] = _ret;
            root["code"] = _code;

            Json::FastWriter writer;
            std::string str = writer.write(root);

            return str;
        }

        bool DeSerislize(std::string &str)
        {
            Json::Value root;
            Json::Reader reader;

            int ret = reader.parse(str, root);
            _ret = root["ret"].asInt();
            _code = root["code"].asInt();

            return ret;
        }
    };
}
